"""
Redis配置模块

提供Redis连接配置和管理功能，支持缓存和消息队列。
"""

from typing import Optional, Any, Dict
import json
import redis.asyncio as redis
from redis.asyncio import Redis
from .settings import settings


class RedisConfig:
    """Redis配置类"""
    
    def __init__(self):
        """初始化Redis配置"""
        self.redis_client: Optional[Redis] = None
        self.cache_client: Optional[Redis] = None
        self.pubsub_client: Optional[Redis] = None
    
    async def connect(self):
        """连接Redis"""
        # 主Redis客户端
        self.redis_client = redis.from_url(
            settings.redis_url,
            encoding="utf-8",
            decode_responses=True,
            socket_keepalive=True,
            socket_keepalive_options={},
            health_check_interval=30,
        )
        
        # 缓存专用客户端
        cache_url = settings.redis_url.replace("/0", "/1")  # 使用DB 1作为缓存
        self.cache_client = redis.from_url(
            cache_url,
            encoding="utf-8", 
            decode_responses=True,
            socket_keepalive=True,
            socket_keepalive_options={},
            health_check_interval=30,
        )
        
        # 发布订阅专用客户端
        pubsub_url = settings.redis_url.replace("/0", "/2")  # 使用DB 2作为发布订阅
        self.pubsub_client = redis.from_url(
            pubsub_url,
            encoding="utf-8",
            decode_responses=True,
            socket_keepalive=True,
            socket_keepalive_options={},
            health_check_interval=30,
        )
    
    async def disconnect(self):
        """断开Redis连接"""
        if self.redis_client:
            await self.redis_client.close()
        if self.cache_client:
            await self.cache_client.close()
        if self.pubsub_client:
            await self.pubsub_client.close()
    
    async def ping(self) -> bool:
        """检查Redis连接状态"""
        try:
            if self.redis_client:
                await self.redis_client.ping()
                return True
            return False
        except Exception:
            return False
    
    async def set_cache(
        self, 
        key: str, 
        value: Any, 
        ttl: Optional[int] = None
    ) -> bool:
        """设置缓存"""
        try:
            if not self.cache_client:
                await self.connect()
            
            # 序列化值
            if isinstance(value, (dict, list)):
                value = json.dumps(value, ensure_ascii=False)
            elif not isinstance(value, str):
                value = str(value)
            
            # 添加前缀
            cache_key = f"{settings.cache_prefix}{key}"
            
            # 设置TTL
            expire_time = ttl or settings.cache_ttl
            
            await self.cache_client.setex(cache_key, expire_time, value)
            return True
        except Exception as e:
            print(f"设置缓存失败: {e}")
            return False
    
    async def get_cache(self, key: str) -> Optional[Any]:
        """获取缓存"""
        try:
            if not self.cache_client:
                await self.connect()
            
            cache_key = f"{settings.cache_prefix}{key}"
            value = await self.cache_client.get(cache_key)
            
            if value is None:
                return None
            
            # 尝试反序列化JSON
            try:
                return json.loads(value)
            except (json.JSONDecodeError, TypeError):
                return value
        except Exception as e:
            print(f"获取缓存失败: {e}")
            return None
    
    async def delete_cache(self, key: str) -> bool:
        """删除缓存"""
        try:
            if not self.cache_client:
                await self.connect()
            
            cache_key = f"{settings.cache_prefix}{key}"
            result = await self.cache_client.delete(cache_key)
            return result > 0
        except Exception as e:
            print(f"删除缓存失败: {e}")
            return False
    
    async def clear_cache(self, pattern: str = "*") -> int:
        """清空缓存"""
        try:
            if not self.cache_client:
                await self.connect()
            
            cache_pattern = f"{settings.cache_prefix}{pattern}"
            keys = await self.cache_client.keys(cache_pattern)
            
            if keys:
                return await self.cache_client.delete(*keys)
            return 0
        except Exception as e:
            print(f"清空缓存失败: {e}")
            return 0
    
    async def publish(self, channel: str, message: Any) -> int:
        """发布消息"""
        try:
            if not self.pubsub_client:
                await self.connect()
            
            # 序列化消息
            if isinstance(message, (dict, list)):
                message = json.dumps(message, ensure_ascii=False)
            elif not isinstance(message, str):
                message = str(message)
            
            return await self.pubsub_client.publish(channel, message)
        except Exception as e:
            print(f"发布消息失败: {e}")
            return 0
    
    async def subscribe(self, *channels: str):
        """订阅频道"""
        try:
            if not self.pubsub_client:
                await self.connect()
            
            pubsub = self.pubsub_client.pubsub()
            await pubsub.subscribe(*channels)
            return pubsub
        except Exception as e:
            print(f"订阅频道失败: {e}")
            return None
    
    async def get_client(self) -> Redis:
        """获取Redis客户端"""
        if not self.redis_client:
            await self.connect()
        return self.redis_client


# 全局Redis配置实例
redis_config = RedisConfig()


async def init_redis():
    """初始化Redis连接"""
    await redis_config.connect()


async def close_redis():
    """关闭Redis连接"""
    await redis_config.disconnect()


# 依赖注入函数
async def get_redis() -> Redis:
    """FastAPI依赖注入：获取Redis客户端"""
    return await redis_config.get_client()


async def get_cache() -> RedisConfig:
    """FastAPI依赖注入：获取缓存客户端"""
    if not redis_config.cache_client:
        await redis_config.connect()
    return redis_config